import re


class Course:
    def __init__(self, name, course_id, content):
        self.name = name
        self.course_id = course_id
        self.content = content
        self.stu_num = 0

    def couse_info(self):
        print(f'课程名称:{self.name} 课程编号:{self.course_id} 课程容量:{self.content} 选课人数:{self.stu_num}')

    @staticmethod
    def check_id(self):
        pattern = r"^C[A-Za-z0-9]{4}"
        if re.fullmatch(pattern, self.course_id):
            return True
        else:
            return False


class Student:
    def __init__(self, name, stu_id):
        self.name = name
        self.stu_id = stu_id
        self.couses = []

    def student_info(self):
        print(f'学生姓名:{self.name} 学生编号:{self.stu_id} 选课列表:', end='')
        for i in self.couses:
            print(i.name, end=' ')
        print()

    @staticmethod
    def check_id(self):
        pattern = r"[0-9]{8}"
        if re.fullmatch(pattern, self.stu_id):
            return True
        else:
            return False


class Teacher:
    def __init__(self, name, work_id):
        self.name = name
        self.work_id = work_id
        self.courses = []

    def teacher_info(self):
        print(f'教师姓名:{self.name} 教师编号:{self.work_id} 课程列表:', end='')
        for i in self.courses:
            print(i.name, end=' ')
        print()


class CourseManager:
    def __init__(self):
        self.courses = {}
        self.students = {}
        self.teacher = {}

    def add_course(self, course):
        if course.check_id(course):
            if course not in self.courses:
                self.courses[course.course_id] = course
                print(f'课程{course.name}添加成功')
            else:
                print(f'课程{course.name}已存在')
        else:
            print(f'课程{course.name}的编号格式不正确')

    def remove_course(self, course):
        if course.course_id in self.courses:
            # 删除课程之前，给所有选此课的学生退课
            print(f'为选{course.name}的学生退课')
            for student in self.students.values():
                if course in student.couses:
                    self.student_withdraw_course(course, student)
            self.courses.pop(course.course_id)
            print(f'课程{course.name}已删除')
        else:
            print(f'课程{course.name}不存在')

    def show_all_courses(self):
        print('系统课程信息')
        for cid, course in self.courses.items():
            course.couse_info()

    def add_student(self, student):
        if student.check_id(student):
            if student.stu_id not in self.students:
                self.students[student.stu_id] = student
                print(f'学生{student.name}添加成功')
            else:
                print(f'学生{student.name}已存在')
        else:
            print(f'学生{student.name}的学号格式不正确')

    def remove_student(self, student):
        if student.stu_id in self.students:
            # 删除学生时，退课
            courses_copy = student.couses.copy()
            for course in courses_copy:
                print('退课', course.name)
                # print('lala', course.name)
                self.student_withdraw_course(course, student)

            self.students.pop(student.stu_id)
            print(f'学生{student.name}已删除')
        else:
            print(f'学生{student.name}不存在')

    def show_all_students(self):
        print('系统学生信息')
        for sid, student in self.students.items():
            student.student_info()

    def add_teacher(self, teacher):
        if teacher.work_id not in self.teacher:
            self.teacher[teacher.work_id] = teacher
            print(f'教师{teacher.name}添加成功')
        else:
            print(f'教师{teacher.name}已存在')

    def rm_teacher(self, teacher):
        if teacher.work_id in self.teacher:
            self.teacher.pop(teacher.work_id)
            print(f'教师{teacher.name}已删除')
        else:
            print(f'教师{teacher.name}不存在')

    def teacher_assign_course(self, course, teacher):
        if course.course_id in self.courses and teacher.work_id in self.teacher:
            teacher.courses.append(course)
            print(f'教师{teacher.name}分配课程{course.name}成功')
        else:
            print('课程或教师不存在')

    def student_select_course(self, course, student):
        if course.course_id in self.courses and student.stu_id in self.students:
            if course.stu_num < course.content:
                if course in student.couses:
                    print(f'学生{student.name}已选本课')
                else:
                    course.stu_num += 1
                    student.couses.append(course)
                print(f'学生{student.name}选课{course.name}成功')
            else:
                print(f'课程{course.name}已满')
        else:
            print('课程或学生不存在')

    def student_withdraw_course(self, course, student):
        if course.course_id in self.courses and student.stu_id in self.students:
            if course in student.couses:
                student.couses.remove(course)
                course.stu_num -= 1
                print(f'学生{student.name}退课{course.name}成功')
            else:
                print(f'学生{student.name}未选本课')
        else:
            print(f'课程{course.name}或学生{student.name}不存在')


if __name__ == '__main__':
    # 测试本模块代码
    course1 = Course('Python', 'Cp001', 2)
    course2 = Course('Java', 'Cj002', 2)
    course3 = Course('C++', 'Cc003', 2)
    zhangsan = Student('张三', '20250001')
    lisi = Student('李四', '20250002')
    wangwu = Student('王五', '2025003b')

    manager = CourseManager()
    manager.add_course(course1)
    manager.add_course(course2)
    manager.add_course(course3)
    manager.add_student(zhangsan)
    manager.add_student(lisi)
    manager.add_student(wangwu)

    manager.student_select_course(course1, zhangsan)
    manager.student_select_course(course2, zhangsan)
    manager.student_withdraw_course(course1, zhangsan)
    manager.student_select_course(course3, zhangsan)
    manager.student_select_course(course1, lisi)
    manager.student_select_course(course2, lisi)
    manager.student_select_course(course3, lisi)

    zhangsan.student_info()
    manager.show_all_courses()
    manager.show_all_students()
    print('---')
    # 删除学生后检查课程信息
    manager.remove_student(lisi)
    manager.show_all_courses()
    manager.show_all_students()

    # 删除课程
    manager.remove_course(course2)

    # 测试老师
    teacher1 = Teacher('张老师', 'T001')
    manager.add_teacher(teacher1)
    manager.teacher_assign_course(course1, teacher1)
    teacher1.teacher_info()
